﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Indie_Game_Contest
{
    class Player : CBaseObject
    {
        //////////////////////////////////////////////////////////////////////////
        // Data Members
        Vector2 velocity = Vector2.Zero;
        bool jumped = false;
        private CatAnimations walk;
        private CatAnimations idle;
        private CatAnimations jumping;
        private CatAnimations attack1;
        private CatAnimations combo2;
        private CatAnimations combo3;
        private int score;

        bool standing, jump, walking;
        private float player_health = 100;
        private int player_live = 3;

        Vector2 prevPos = Vector2.Zero;
        private static int wait = 0;
        bool flip;
        bool combo_started, combo1, attack2, attack3;
        private static int combo_timer;
        private static int count;

        float atkTimer = 0.0f;

        //////////////////////////////////////////////////////////////////////////
        // Methods
        public Player()
        {
            type = ObjectType.Player;
        }
        public override void LoadContent(Rectangle sourceRect, Vector2 vPos, Color mask, Texture2D tImage, float fRotation, float fScale, int nWidth, int nHeight, int nID)
        {
        }

        public bool Take_Damage(float dmg)
        {
            player_health -= dmg;
            if (player_health <= 0)
                MessageSystem.Instance.SendMessage(new PlayerDeadMessage());
            return false;
        }
        public void IncreaseGossip(float amt)
        {
            player_health += amt;

            if (player_health >= 100)
            {
                player_health = 0;
                player_live += 1;
            }
        }

        public override void Render()
        {
            //  WorldData.spriteBatch.Draw(TextureManager.Instance.GetTexture(textureID),
            // position,null,
            // colorMask, 0, center,1, SpriteEffects.None, 0);
            if (walking)
            {
                walk.Draw(WorldData.spriteBatch, new Vector2(position.X, position.Y), new Vector2(0, 3), 0.0f, scale, flip);


            }
            else if (jump)
            {

                jumping.Draw(WorldData.spriteBatch, new Vector2(position.X, position.Y), new Vector2(2, 2), 0.0f, scale, flip);
            }
            else if (standing)
                idle.Draw(WorldData.spriteBatch, new Vector2(position.X, position.Y), new Vector2(1, 0), 0.0f, scale, flip);
            if (combo_started)
            {
                if (combo1)
                {
                    Attack1.Draw(WorldData.spriteBatch, new Vector2(position.X, position.Y), new Vector2(4, 7), 0.0f, scale, flip);

                }
                else if (attack2)
                {
                    Combo2.Draw(WorldData.spriteBatch, new Vector2(position.X, position.Y), new Vector2(5, 0), 0.0f, scale, flip);

                }
                else if (attack3)
                {
                    Combo2.Draw(WorldData.spriteBatch, new Vector2(position.X, position.Y), new Vector2(5, 2), 0.0f, scale, flip);

                }


            }

        }

        public override CollisionSide CheckCollision(CBaseObject obj)
        {
            CollisionSide side = base.CheckCollision(obj);

            if (obj.Type == ObjectType.Tile && side != CollisionSide.None)
            {
                switch (side)
                {
                    case CollisionSide.Bottom:
                        {
                            if ((obj.Position.Y - position.Y) >= (obj.Center.Y * obj.Scale))
                            {
                                jumped = false;
                                position.Y = obj.Position.Y - (center.Y + obj.Center.Y * obj.Scale);
                            }
                            break;
                        }
                    case CollisionSide.Top:
                        {
                            if (position.X < obj.Position.X + obj.Center.X * obj.Scale &&
                                position.X > obj.Position.X - obj.Center.X * obj.Scale)
                                position.Y = prevPos.Y;

                            break;
                        }
                    case CollisionSide.Right:
                        position.X = obj.Position.X - (obj.Center.X * obj.Scale + center.X);
                        break;
                    case CollisionSide.Left:
                        position.X = obj.Position.X + obj.Center.X * obj.Scale + center.X;
                        break;
                }
            }

            return side;
        }

        public override void Update(float dt)
        {
            prevPos = position;

            velocity.Y += 70;

            if (velocity.Y >= 750)
                velocity.Y = 750;

            position += velocity * dt;

            walk.Update(5);
            jumping.Update(1);
            idle.Update(10);
            Attack1.Update(15);
            Combo2.Update(15);
            Combo3.Update(15);
            Input(dt);

            if (position.X > WorldData.WindowWidth + 5 + center.X * scale)
                position.X = -(center.X * scale);
            else if (position.X < -(center.X * scale) - 5)
                position.X = WorldData.WindowWidth + center.X * scale;

            //velocity.X = 0;
            if (combo_started)
            {

                if (count % 3 == 0)
                {

                }
                //combo_timer++;
            }
        }
        void Input(float dt)
        {
            CInput input = CInput.Instance;
            GamePadState controllerState = GamePad.GetState(PlayerIndex.One);

            atkTimer += dt;

            // Movement
            if (!controllerState.IsConnected)
            {
                if (input.KeyDown(Keys.A) || input.KeyDown(Keys.Left))
                {
                    wait = 0;
                    combo1 = false;
                    attack2 = false;
                    attack3 = false;
                    walking = true;
                    standing = false;
                    jump = false;
                    position.X -= 250 * dt;
                    flip = true;
                }
                else
                    wait++;
                if (input.KeyDown(Keys.D) || input.KeyDown(Keys.Right))
                {
                    walking = true;
                    combo1 = false;
                    attack2 = false;
                    attack3 = false;
                    wait = 0;
                    standing = false;
                    jump = false;
                    position.X += 250 * dt;

                    if (flip)
                    {
                        flip = false;
                    }
                }
                else
                    wait++;

                if (!jumped && (input.KeyPressed(Keys.W) || input.KeyPressed(Keys.Up)) )
                {
                    velocity.Y = -750;
                    jumped = true;
                    jump = true;
                    walking = false;
                    standing = false;
                    wait = 0;
                }
                else
                    wait++;

                if (input.KeyPressed(Keys.Space) && atkTimer >= .3f)
                {
                    atkTimer = 0.0f;

                    AudioManager.Instance.PlaySFX("punch");

                    // Check nearby enemies for attack range
                    List<CBaseObject> enemies = ObjectManager.Instance.Objects;

                    foreach (CBaseObject obj in enemies)
                    {
                        if (obj.Type == ObjectType.Enemy)
                        {
                            Enemy enemy = (Enemy)obj;

                            Vector2 dir;

                            if (!flip)
                                dir = new Vector2(-1, 0);
                            else
                                dir = new Vector2(1, 0);

                            Vector2 norm = position - enemy.Position;
                            float length = norm.Length();
                            norm.Normalize();

                            norm.X /= Math.Abs(norm.X);

                            if (length < center.X * scale + enemy.Center.X * enemy.Scale + 32 && norm.X == dir.X)
                            {
                                // Deal damage to those close enough to take a fist to the face
                                enemy.Take_Damage(20);

                                norm.Normalize();
                                enemy.Velocity += new Vector2(norm.X * -280,0);

                                //AudioManager.Instance.PlaySFX("Menu_Move");
                            }
                        }
                    }
                    combo_started = true;
                    if (combo_timer == 0)
                    {
                        standing = false;
                        combo1 = true;
                        attack2 = false;
                        attack3 = false;
                        jump = false;
                        wait = 0;
                        walking = false;
                        combo_timer++;
                    }
                    else if (combo_timer == 1)
                    {

                        standing = false;
                        combo1 = false;
                        attack2 = true;
                        attack3 = false;
                        jump = false;
                        wait = 0;
                        walking = false;
                        combo_timer++;

                    }
                    else
                    {
                        standing = false;
                        combo1 = false;
                        attack2 = false;
                        attack3 = true;
                        jump = false;
                        wait = 0;
                        walking = false;
                        combo_timer = 0;

                    }
                    // Send a message if one has died
                }
                else
                    wait++;
            }
            else
            {
                if (Math.Abs(controllerState.ThumbSticks.Left.X) > .3f)
                {
                    position.X += controllerState.ThumbSticks.Left.X * dt;

                    if (controllerState.ThumbSticks.Left.X > 0)
                    {
                        walking = true;
                        combo1 = false;
                        attack2 = false;
                        attack3 = false;
                        wait = 0;
                        standing = false;
                        jump = false;
                        position.X += 250 * dt;

                        if (flip)
                        {
                            flip = false;
                        }
                    }
                    else
                    {
                        wait = 0;
                        combo1 = false;
                        attack2 = false;
                        attack3 = false;
                        walking = true;
                        standing = false;
                        jump = false;
                        position.X -= 250 * dt;
                        flip = true;
                    }
                }
                else
                    wait++;

                if (!jumped && controllerState.ThumbSticks.Left.Y > .5f)
                {
                    velocity.Y = -750;
                    jumped = true;
                    jump = true;
                    walking = false;
                    standing = false;
                    wait = 0;
                }
                else
                    wait++;

                if (input.GamePadButtonPressed(Buttons.X) && atkTimer >= .5f)
                {
                    AudioManager.Instance.PlaySFX("punch");

                    // Check nearby enemies for attack range
                    List<CBaseObject> enemies = ObjectManager.Instance.Objects;

                    foreach (CBaseObject obj in enemies)
                    {
                        if (obj.Type == ObjectType.Enemy)
                        {
                            Enemy enemy = (Enemy)obj;

                            Vector2 dir;

                            if (!flip)
                                dir = new Vector2(-1, 0);
                            else
                                dir = new Vector2(1, 0);

                            Vector2 norm = position - enemy.Position;
                            float length = norm.Length();
                            norm.Normalize();

                            norm.X /= Math.Abs(norm.X);

                            if (length < center.X * scale + enemy.Center.X * enemy.Scale && norm.X + 24 == dir.X)
                            {
                                // Deal damage to those close enough to take a fist to the face
                                enemy.Take_Damage(35);

                                norm.Normalize();
                                enemy.Velocity += new Vector2(norm.X * -280, 0);

                                //AudioManager.Instance.PlaySFX("Menu_Move");
                            }
                        }
                    }
                    combo_started = true;
                    if (combo_timer == 0)
                    {
                        standing = false;
                        combo1 = true;
                        attack2 = false;
                        attack3 = false;
                        jump = false;
                        wait = 0;
                        walking = false;
                        combo_timer++;
                    }
                    else if (combo_timer == 1)
                    {

                        standing = false;
                        combo1 = false;
                        attack2 = true;
                        attack3 = false;
                        jump = false;
                        wait = 0;
                        walking = false;
                        combo_timer++;

                    }
                    else
                    {
                        standing = false;
                        combo1 = false;
                        attack2 = false;
                        attack3 = true;
                        jump = false;
                        wait = 0;
                        walking = false;
                        combo_timer = 0;

                    }
                    // Send a message if one has died
                }
                else
                    wait++;
            }
            if (wait > 4)
            {
                standing = true;
                walking = false;
                jump = false;
            }
            if (wait > 15)
            {
                combo_started = false;
                combo1 = false;
                attack2 = false;
                attack3 = false;
                //combo_timer = 0;
            }
        }

        //////////////////////////////////////////////////////////////////////////
        // Properties
        public int Score
        {
            get { return score; }
            set { score = value; }
        }

        internal CatAnimations Jumping
        {
            get { return jumping; }
            set { jumping = value; }
        }
        internal CatAnimations Idle
        {
            get { return idle; }
            set { idle = value; }
        }
        public int Player_live
        {
            get { return player_live; }
            set { player_live = value; }
        }
        public float Player_health
        {
            get { return player_health; }
            set { player_health = value; }
        }
        public CatAnimations Walk
        {
            get { return walk; }
            set { walk = value; }
        }
        public CatAnimations Combo3
        {
            get { return combo2; }
            set { combo2 = value; }
        }

        public CatAnimations Combo2
        {
            get { return combo2; }
            set { combo2 = value; }
        }


        public CatAnimations Attack1
        {
            get { return attack1; }
            set { attack1 = value; }
        }

        public Microsoft.Xna.Framework.Vector2 Velocity
        {
            get { return velocity; }
            set { velocity = value; }
        }
    }
}
